package org.ndx.majick.ui.number;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSpinner;

import org.ndx.majick.properties.Property;
import org.ndx.majick.ui.IClassUIProvider;
import org.ndx.majick.ui.IPropertyUIMetadata;
import org.ndx.majick.ui.object.ObjectUIProvider;

/**
 * Number UI Provider allows rendering of all numbers subtypes.
 * @author Nicolas Delsaux
 *
 */
public class NumberUIProvider extends ObjectUIProvider implements
		IClassUIProvider {

	/**
	 * Number edited type
	 */
	private final Class<? extends Number> type;

	public NumberUIProvider(Class<? extends Number> type) {
		this.type = type;
	}

	@Override
	public NumberPropertyMetadata createMetadata() {
		return new NumberPropertyMetadata(type);
	}
	
	@Override
	public JComponent getEditor(IPropertyUIMetadata metadata, Property<?> source) {
		NumberPropertyMetadata numberMetadata = (NumberPropertyMetadata) metadata;
		JSpinner returned = new JSpinner(new NumberBackedSpinnerModel((Property<? extends Number>) source, numberMetadata));
		configureEditor(returned, numberMetadata, source);
		return returned;
	}

	public JComponent getViewer(final IPropertyUIMetadata metadata, final Property<?> source) {
		final NumberPropertyMetadata numberMetadata = (NumberPropertyMetadata) metadata;
		final JLabel returned = new JLabel();
		setViewText(returned, numberMetadata, (Property<? extends Number>) source);
		source.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				setViewText(returned, numberMetadata, (Property<? extends Number>) source);
			}
		});
		configureViewer(returned, metadata, source);
		return returned;
	}

	private void setViewText(JLabel returned,
			NumberPropertyMetadata numberMetadata, Property<? extends Number> source) {
		returned.setText(numberMetadata.getViewFormat().get().format(source.get()));
	}

	public Class<? extends Number> getType() {
		return type;
	}
}
